package com.ziytek.web.citizen.service;

import com.ziytek.web.citizen.config.caffeine.CaffeineUtil;
import com.ziytek.web.citizen.mapper.BoardConfigMapper;
import com.ziytek.web.citizen.mapper.DoorMapper;
import com.ziytek.web.citizen.pojo.basic.BoardConfig;
import com.ziytek.web.citizen.pojo.basic.DoorConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author fengh
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DoorsService {
    private final DoorMapper doorMapper;
    private final BoardConfigMapper boardConfigMapper;

    public List<DoorConfig> getDoorsConfig() {
        List<DoorConfig> doors = CaffeineUtil.get(CaffeineUtil.CACHE_KEY_DOORS_CONFIG);
        if (!CollectionUtils.isEmpty(doors)) {
            return doors;
        }

        doors = doorMapper.queryAllList();
        CaffeineUtil.set(CaffeineUtil.CACHE_KEY_DOORS_CONFIG, doors, 24 * 60 * 60);

        return doors;
    }

    public List<Integer> getBoardNoList() {
        List<Integer> boardNoList = CaffeineUtil.get(CaffeineUtil.CACHE_KEY_DOORS_NO);
        if (!CollectionUtils.isEmpty(boardNoList)) {
            return boardNoList;
        }

        var doors = getDoorsConfig();
        boardNoList = new LinkedList<>();
        for (var door : doors) {
            var boardAddress = boardConfigMapper.queryByDoorListNum(door.getDoor());
            if (boardAddress == null) {
                continue;
            }
            boardNoList.addAll(boardAddress);
        }

        if (boardNoList.isEmpty()) {
            return Collections.emptyList();
        }

        CaffeineUtil.set(CaffeineUtil.CACHE_KEY_DOORS_NO, boardNoList, 24 * 60 * 60);

        return boardNoList;
    }

    public Pair<Set<Integer>, List<String>> getBoardNos(String queryDoor) {
        Pair<Set<Integer>, List<String>> pair = CaffeineUtil.get(CaffeineUtil.CACHE_KEY_DOORS_NO_PAIR + queryDoor);
        if (null != pair) {
            return pair;
        }

        List<DoorConfig> doors = getDoorsConfig();
        if (CollectionUtils.isEmpty(doors)) {
            return null;
        }

        List<String> doorNos = new ArrayList<>();
        doors.forEach(d -> {
            if (StringUtils.isNotEmpty(queryDoor) && queryDoor.equalsIgnoreCase(d.getDoor())) {
                doorNos.add(d.getDoor());
            }
        });

        if (CollectionUtils.isEmpty(doorNos)) {
            return null;
        }

        List<BoardConfig> boardConfigs = boardConfigMapper.queryAllListByDoor(doorNos);
        if (CollectionUtils.isEmpty(boardConfigs)) {
            return null;
        }

        Set<Integer> boardNos = new HashSet<>();
        for (var boardConfig : boardConfigs) {
            boardNos.add(boardConfig.getAddress());
        }

        var p = Pair.of(boardNos, doorNos);
        CaffeineUtil.set(CaffeineUtil.CACHE_KEY_DOORS_NO_PAIR + queryDoor, p, 30 * 60);
        return p;
    }
}
